#define _DLL_PRODUCT
#include "core.h"

CProduct::CProduct()
{
	m_pApi = new CApi(this);
}

CProduct::~CProduct()
{
	delete m_pApi;
	m_pApi = NULL;
}

CProduct* CProduct::getInstance()
{
	static CProduct* p = NULL;
	if (!p)
	{
		p = new CProduct;
	}
	return p;
}

bool CProduct::Initialize(std::string product)
{
	return true;
}

bool CProduct::Destory(std::string product)
{
	delete this;
	return true;
}

bool CProduct::Request(std::string queryParam, std::string actionName)
{
	m_actionName = actionName;

	if (m_method == "GET")
	{
		m_queryUrl += "/?";
		m_queryUrl += queryParam;
		if (send_curl(m_queryUrl.c_str()) == false)
		{
			return false;
		}
	}
	else if (m_method == "POST")
	{

		if (send_curl(m_queryUrl.c_str(), queryParam.c_str(), "POST") == false)
		{
			return false;
		}
/*
 		CURL *curl;
		CURLcode res;
 
 		curl = curl_easy_init();
 
 		if (!curl) {
 			return false;
 		}
 
		memset(&g_buf_tmp, 0, sizeof(g_buf_tmp));
		g_buf_tmp.len = 0;

 		char error_buffer[MAX_DATA_SIZE];
 		curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, error_buffer);
		curl_easy_setopt(curl, CURLOPT_TIMEOUT, 10);
		curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 10);
		curl_easy_setopt(curl, CURLOPT_URL, m_queryUrl.c_str());
		curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1);
 		curl_easy_setopt(curl, CURLOPT_WRITEDATA, &g_buf_tmp);
 		curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, writer);
		curl_easy_setopt(curl, CURLOPT_POSTFIELDS, queryParam.c_str());
 
 		res = curl_easy_perform(curl);
 
 		if (res != CURLE_OK) {
 			printf("curl_easy_perform() failed: %s", curl_easy_strerror(res));
 			return false;
 		}
	*/
	}
	
	return true;
}

bool CProduct::Response(SResponseMap &mapResult)
{
	if (m_retFormat == "JSON")
	{
		Json::Reader reader;
		Json::Value result;
		printf("%s\n", g_buf_tmp.data);
		if (reader.parse(g_buf_tmp.data, result))
		{
			std::vector<struct SMember>::iterator itor_member = mapResult.members.begin();
			for (; itor_member!=mapResult.members.end(); itor_member++)
			{
				itor_member->value = result[itor_member->tagName].asString();
			}

			std::vector<struct SResponseMap*>::iterator itor_struct = mapResult.vStructNode.begin();
			for (; itor_struct!=mapResult.vStructNode.end(); itor_struct++)
			{
				itor_member = (*itor_struct)->members.begin();
				for (; itor_member!=(*itor_struct)->members.end(); itor_member++)
				{
					itor_member->value = result[(itor_member->tagName)].asString();
				}
			}

			std::vector<struct SResponseMap*>::iterator itor_arrays = mapResult.vArraysNode.begin();
			for (; itor_arrays!=mapResult.vArraysNode.end(); itor_arrays++)
			{
				itor_member = (*itor_arrays)->members.begin();
				for (; itor_member!=(*itor_arrays)->members.end(); itor_member++)
				{
					itor_member->value = result[(itor_member->tagName)].asString();
				}
			}
		}
	}
	else if (m_retFormat == "XML")
	{
 		TiXmlDocument myDocument;
 		myDocument.Parse(g_buf_tmp.data);
		printf("%s\n", g_buf_tmp.data);
 
 		const TiXmlElement *pRoot = myDocument.RootElement();
		
		if (!pRoot)
		{
			return false;
		}
 
		const TiXmlElement *p = NULL;
		const TiXmlElement *pp = NULL;
		std::vector<struct SMember>::iterator itor_member = mapResult.members.begin();
		for (; itor_member!=mapResult.members.end(); itor_member++)
		{
			p = pRoot->FirstChildElement(itor_member->tagName.c_str());
			itor_member->value = p->GetText();
		}

		std::vector<struct SResponseMap*>::iterator it_arrays = mapResult.vArraysNode.begin();
		for (; it_arrays!=mapResult.vArraysNode.end(); it_arrays++)
		{
			itor_member = (*it_arrays)->members.begin();
			p = pRoot->FirstChildElement((*it_arrays)->tagName.c_str());
			if (!(*it_arrays)->itemName.empty())
			{
				pp = p->FirstChildElement((*it_arrays)->itemName.c_str());
				p = pp;
			}
			if (p)
			{
				for (; itor_member!=(*it_arrays)->members.end(); itor_member++)
				{
					pp = p->FirstChildElement(itor_member->tagName.c_str());
					itor_member->value = pp->GetText();
				}
			}
		}

		std::vector<struct SResponseMap*>::iterator it_structs = mapResult.vStructNode.begin();
		for (; it_structs!=mapResult.vStructNode.end(); it_structs++)
		{
			itor_member = (*it_structs)->members.begin();
			p = pRoot->FirstChildElement((*it_structs)->tagName.c_str());
			if (!(*it_structs)->itemName.empty())
			{
				pp = p->FirstChildElement((*it_structs)->itemName.c_str());
				p = pp;
			}
			if (p)
			{
				for (; itor_member!=(*it_structs)->members.end(); itor_member++)
				{
					pp = p->FirstChildElement(itor_member->tagName.c_str());
					itor_member->value = pp->GetText();
				}
			}
		}

/*		std::vector<struct SResponseMap*>::iterator itor_struct = mapResult.vStructNode.begin();
		for (; itor_struct!=mapResult.vStructNode.end(); itor_struct++)
		{
			itor_member = (*itor_struct)->members.begin();
			for (; itor_member!=(*itor_struct)->members.end(); itor_member++)
			{
				itor_member->value = result[(itor_member->tagName)].asString();
			}
		}

		std::vector<struct SResponseMap*>::iterator itor_arrays = mapResult.vArraysNode.begin();
		for (; itor_arrays!=mapResult.vArraysNode.end(); itor_arrays++)
		{
			itor_member = (*itor_arrays)->members.begin();
			for (; itor_member!=(*itor_arrays)->members.end(); itor_member++)
			{
				itor_member->value = result[(itor_member->tagName)].asString();
			}
		}

		MAP_RESPONSE_RESULT_MAP::iterator itResultMapping = mapResult.find("resultMapping");
 		if (itResultMapping != mapResult.end())
 		{
 			for (MAP_RESPONSE_MEMBERS::iterator it=itResultMapping->second.begin(); it!=itResultMapping->second.end(); it++)
 			{
 				it->second.value = p->Attribute(rootName.c_str());
 			}
 		}
 		itResultMapping = mapResult.find("arrays");
 		if (itResultMapping != mapResult.end())
 		{
 			for (MAP_RESPONSE_MEMBERS::iterator it=itResultMapping->second.begin(); it!=itResultMapping->second.end(); it++)
 			{
 				it->second.value = p->Attribute(rootName.c_str());
 			}
 		}
*/
	}
	
	return true;
}

void CProduct::setDomain(std::string domain)
{
	m_queryUrl = domain;
}

void CProduct::setBaseParameter(std::string AccessKeyId, std::string AccessKeySecret, std::string ResourceOwnerAccount, std::string retFormat, std::string method, std::string protocol)
{
	m_accessKeyId = AccessKeyId;
	m_accessKeySecret = AccessKeySecret;
	m_resourceOwnerAccount = ResourceOwnerAccount;
	m_retFormat = retFormat;
	m_method = method;
	m_protocol = protocol;
}